package com.hy.study.utils;

import org.apache.commons.beanutils.BeanUtils;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;

/**
 * @author huyong
 * @date 2024 年 01 月 15 日 16:18: 42
 */
public class PropertiesUtils {

    public static Properties loadProperties(String propertiesFile) throws Exception {
        Properties properties = new Properties();
        properties.load(PropertiesUtils.class.getClassLoader().getResourceAsStream(propertiesFile));
        return properties;
    }

    /**
     * 判断是否为包装类型
     *
     * @param clz
     *
     * @return
     */
    private static boolean isPrimitive(Class clz) {
        if (clz.isPrimitive()) {
            return true;
        }
        try {
            return ((Class) clz.getField("TYPE").get(null)).isPrimitive();
        } catch (Exception e) {
            return false;
        }
    }

    public static <T> T toBean(Properties properties, Class<T> type, String prefix) throws Exception {
        if (prefix == null) {
            prefix = "";
        } else if (!prefix.isEmpty() && !prefix.endsWith(".")) {
            prefix += ".";
        }
        T obj = type.newInstance();
        BeanInfo bean = Introspector.getBeanInfo(type);// 内省方式来初始化
        PropertyDescriptor[] propertyDescriptors = bean.getPropertyDescriptors();
        for (PropertyDescriptor descriptor : propertyDescriptors) {
            Class fieldType = descriptor.getPropertyType();// 只支持基本数据类型的拷贝
            if (fieldType == Class.class) {
                continue;
            }
            if (isPrimitive(fieldType) || fieldType == String.class) {// 支持基本类型的转换，如果使用 PropertyUtils, 则不会实现基本类型 + String的自动转换
                BeanUtils.setProperty(obj, descriptor.getName(), properties.getProperty(prefix + descriptor.getName()));
            } else {
                BeanUtils.setProperty(obj, descriptor.getName(), toBean(properties, fieldType, prefix + descriptor.getName()));// 这里做了递归处理
            }
        }
        return obj;
    }
}
